package src.week4.实践;


import src.week2.EmptyCollectionException;
import src.week4.ElementNotFoundException;
import src.week4.ListADT;
import src.week4.实践.Product;

import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

public abstract class LinkedList<T> implements ListADT<T>, Iterable<T>
{
    protected int count;
    protected LinearNode<T> head, tail;
    protected int modCount;


    public LinkedList()
    {
        count = 0;
        head = tail = null;
        modCount = 0;
    }




    @Override
    public T removeFirst() throws EmptyCollectionException
    {
        head=head.getNext();
        count--;
        return null;
    }


    @Override
    public T removeLast() throws EmptyCollectionException
    {
        if (head==null){
            throw new EmptyCollectionException("LinkedList");
        }
        if (head.getNext()==null){
            head=null;
            tail=null;
        }
        else {
            LinearNode temp=head;
            while (head.getNext()!=null){
                if (temp.getNext()==tail){
                    tail=temp;
                    tail.setNext(null);
                    break;
                }
                temp=temp.getNext();
            }
        }
        count--;
        return null;
    }


    @Override
    public T remove(T targetElement) throws EmptyCollectionException,
            ElementNotFoundException
    {
        if (isEmpty()) {
            throw new EmptyCollectionException("LinkedList");
        }

        boolean found = false;
        LinearNode<T> previous = null;
        LinearNode<T> current = head;

        while (current != null && !found)
            if (targetElement.equals(current.getElement()))
                found = true;
            else
            {
                previous = current;
                current = current.getNext();
            }

        if (!found)
            throw new ElementNotFoundException("LinkedList");

        if (size() == 1)  // only one element in the list
            head = tail = null;
        else if (current.equals(head))  // target is at the head
            head = current.getNext();
        else if (current.equals(tail))  // target is at the tail
        {
            tail = previous;
            tail.setNext(null);
        }
        else  // target is in the middle
            previous.setNext(current.getNext());

        count--;
        modCount++;

        return current.getElement();
    }


    @Override

    public T first() throws EmptyCollectionException
    {
        LinearNode node =head;
        return (T) node.getElement();
    }
    @Override
    public T last() throws EmptyCollectionException
    {
        LinearNode node = head;
        while (node != null) {
            node = node.getNext();
            }
            return (T) node.getElement();
        }
    @Override
    public boolean contains(T targetElement) throws
            EmptyCollectionException
    {
        return false;
    }
    @Override
    public boolean isEmpty()
    {
        if (head.getElement()==null){
            return true;
        }
        else {
            return false;
        }
    }
    @Override
public int size()
{
    return count;
}

 public boolean Find(T element){
    boolean find = false;
    LinearNode<T> previous = null;
    LinearNode<T> current=head;
    while (current!=null&&!find){
        if (element.equals(current.getElement())){
            find=true;
            break;
        }
        else {
            current=current.getNext();
        }
    }
    return find;
}
    public void selectSorting(){
        Product temp;
        LinearNode<Product> current = (LinearNode<Product>) head;
        while (current!=null){
            LinearNode<Product> node = current.getNext();
            while (node!=null){
                if (node.getElement().compareTo(current.getElement())<0){
                    temp= (Product) node.getElement();
                    node.setElement(current.getElement());
                    current.setElement(temp);
                }
                node=node.getNext();
            }
            current=current.getNext();
        }
    }
    @Override
    public String toString()
    {
        LinearNode temp=head;
        String result="";
        while (temp!=null){
            System.out.println(temp.getElement()+" ");
            // result+=temp.getElement()+" ";
            temp=temp.getNext();
        }
        return "";
    }

    @Override
    public Iterator<T> iterator()
    {
        return new LinkedListIterator();
    }


    private class LinkedListIterator implements Iterator<T>
    {
        private int iteratorModCount;  // the number of elements in the collection
        private LinearNode<T> current;  // the current position


        public LinkedListIterator()
        {
            current = head;
            iteratorModCount = modCount;
        }


        @Override
        public boolean hasNext() throws ConcurrentModificationException
        {
            if (iteratorModCount != modCount) {
                throw new ConcurrentModificationException();
            }

            return (current != null);
        }


        @Override
        public T next() throws ConcurrentModificationException
        {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }

            T result = current.getElement();
            current = current.getNext();
            return result;
        }


        @Override
        public void remove() throws UnsupportedOperationException
        {
            throw new UnsupportedOperationException()  ;
        }
    }

}



